/*
 * @Author: your name
 * @Date: 2021-09-10 09:20:05
 * @LastEditTime: 2021-09-23 14:06:46
 * @LastEditors: Please set LastEditors
 * @Description: 666
 * @FilePath: \gitee-kubife\biaozhu_20210910\js\index.js
 */
(function() {
    /* 画布... */
    function BZ_Canvas(opt) {
        var opt = opt || {};
        this.opt = $.extend({
            id: "",
            imageSrc: ""
        }, opt);
        // --- 画布宽度(默认屏幕宽)
        this.full_screen_width = opt.ww || window.innerWidth;
        // --- 画布高度(默认屏幕高)
        this.full_screen_height = opt.wh || window.innerHeight;
        // --- 要绘制的图片DOM
        this.image = null;
        // --- konva的image
        this.konva_image = null;
        // --- konva_image的拖拽
        //this.ki_dragable = false;
        // --- konva_transform_image
        this.konva_transform_image = null;
        // --- 图片的缩放比例(默认1)
        this.image_scale = 1;
        // --- 最小缩放比例1
        this.MININUM_SCALE = 1;
        // --- 画布的X轴坐标(默认左上角0)
        this.ctx_x = 0;
        // --- 画布的Y轴坐标(默认左上角0)
        this.ctx_y = 0;
        // --- 是否拖拽平移
        this.dragging = false;
        // --- 鼠标按下时的坐标信息
        this.image_md_pos = null;
        // --- 鼠标移动时的坐标信息
        this.image_mm_pos = null;
        // --- 鼠标抬起时的坐标信息
        this.image_mu_pos = null;
        /* ------------------------------------------- */
        // --- 存Konva_layer
        this.layers = [];
        // --- stage的mousemove事件，要先执行mousedown再触发
        this.state_mousedown = false;
        /* ------------------------------------------- */
        /* ------------------------------------------- */
        // --- 
        /* ------------------------------------------- */
        if (opt.id) {
            // --- Konva_stage
            this.stage = new Konva.Stage({
                container: opt.id,
                width: this.full_screen_width,
                height: this.full_screen_height
            });
            console.log("---this.stage---", this.stage);
            // --- 添加Konva_layer
            this.layers.push(
                new Konva.Layer(
                    /* {
                                        x:0,
                                        y:0,
                                        width: this.full_screen_width,
                                        height: this.full_screen_height
                                    } */
                )
            );
            // --- Konva_layer -> Konva_stage
            this.stage.add(
                this.layers[0]
            );
            // --- 初始化
            this.init();
        } else {
            console.error("需要container...");
        }
    }
    BZ_Canvas.prototype = {
        constructor: BZ_Canvas,
        // --- 初始化
        init() {
            var _this = this;
            // ---
            this.addImage().then(
                function() {
                    // ---
                    _this.stageBindEvents();
                }
            );
        },
        // --- 默认添加一张图片
        addImage() {
            if (!this.opt.imageSrc) {
                return console.error("缺少图片链接地址...");
            }
            var _this = this;
            this.image = new Image();
            this.image.src = this.opt.imageSrc;
            return $.Deferred(function(defer) {
                _this.image.onload = function() {
                    // --- 
                    _this.konva_image = new Konva.Image({
                        x: _this.full_screen_width / 2 - _this.image.width * 2 / 2,
                        y: 50,
                        image: _this.image,
                        width: _this.image.width * 2,
                        height: _this.image.height * 2,
                        draggable: true
                    });
                    //console.log("---_this.konva_image---", _this.konva_image);
                    // _this.konva_image.on("dragstart",function(){
                    //     //alert("dragstart");
                    //     _this.ki_dragable = true;
                    // });
                    // _this.konva_image.on("dragend",function(){
                    //     //alert("dragend");
                    //     _this.ki_dragable = false;
                    // });
                    _this.layers[0].add(
                        _this.konva_image
                    );
                    // --- 图片设置变换
                    // _this.konva_transform_image = new Konva.Transformer({
                    //     node: _this.konva_image,
                    //     centeredScaling: true
                    // });
                    // ---
                    // _this.layers[0].add(
                    //     _this.konva_transform_image
                    // );
                    // ---
                    _this.layers[0].draw();
                    // ---
                    //console.log("---_this.layers[0]---",_this.layers[0]);
                    defer.resolve();
                };
            });
        },
        // --- Konva_stage绑定事件
        stageBindEvents() {
            var _this = this;
            // --- mousedown
            this.stage.on("mousedown", function(mdi) {
                //console.log("---stage_mousedown_info---",mdi);
                // --- 回调外部调用
                //_this.opt.stageMDCBF && _this.opt.stageMDCBF(mdi, _this);
                // --- 
                //_this.state_mousedown = true;
            });
            // --- mousemove
            this.stage.on("mousemove", _.debounce(function(mmi) {
                // --- 
                if (!_this.state_mousedown) return false;
                //console.log("---stage_mousemove_info---",mmi);
            }, 16));
            // --- mouseup
            this.stage.on("mouseup", function(mui) {
                // --- 回调外部调用
                _this.opt.stageMUCBF && _this.opt.stageMUCBF(mui, _this);
                // ---
                _this.state_mousedown = false;
            });
            // --- 
        }
    };
    /* 点 + 线 */
    function BZ_CirclePlusLine(opt) {
        // --- 外部stage中的Layer
        this.parentLayer = opt.parentLayer;
        // --- circle 点所在的Group
        this.circleGroup = new Konva.Group({
            x:0,
            y:0
        });
        //console.log("---this.circleGroup---",this.circleGroup);
        // --- line 线所在的Group
        this.lineGroup = new Konva.Group({
            x:0,
            y:0
        });
        //console.log("---this.lineGroup---",this.lineGroup);
        // --- Konva_line
        this.line = null;
        // --- lineOptions(默认)
        this.lineOptions = {
            points: [/* 100,100,200,200,300,300 */],
            fill: "rgba(255,215,0,.25)",
            stroke: 'yellow',
            strokeWidth: 4,
            lineJoin: 'round',
            //tension: 1, // --- 样条曲线
            closed: true, // --- 多段线自动闭合???
            /*
             * line segments with a length of 33px
             * with a gap of 10px
             */
            //dash: [33, 10]
        };
        // --- points(绘制line线段时用line.setPoints(this.points)) 
        this.points = [];
        // --- circleOptions(默认)
        this.circleOptions = {
            x: "",
            y: "",
            radius: 8,
            fill: 'pink',
            stroke: '#fff',
            strokeWidth: 2,
            draggable: true
        };
        // ---
        this.addLine();
        // ---
        var _this = this;
        // ---
        $.Deferred(function(defer){
            _.delay(defer.resolve,0);
        }).then(
            function(){
                _this.parentLayer.add(
                    _this.lineGroup,
                    _this.circleGroup
                );
            }
        );
    }
    BZ_CirclePlusLine.prototype = {
        constructor: BZ_CirclePlusLine,
        // --- 创建line
        addLine(options) {
            var _this = this;
            var opt = $.extend(
                true, {},
                this.lineOptions,
                options || {}
            );
            this.line = new Konva.Line(opt);
            //console.log("---this.line---",this.line);
            this.lineGroup.add(
                this.line
            );
            //console.log("---this.lineGroup---",this.lineGroup);
            // ---
            this.line.on("mouseenter",function(){
                _this.line.setStrokeWidth(8);
                _this.parentLayer.draw();
            });
            // ---
            this.line.on("mouseout",function(){
                _this.line.setStrokeWidth(4);
                _this.parentLayer.draw();
            });
            // --- 点击线段添加circle
            this.line.on("mouseup", function(mui) {
                //console.log("---mui---", mui);
                //alert("add circle by line mouseup");
                // --- 阻止事件冒泡
                mui.cancelBubble = true;
                // --- 加一个点
                _this.addCircle({
                    x: mui.evt.clientX,
                    y: mui.evt.clientY
                });
                // --- 修改this.circleGroup.children中的circle顺序
                /* console.log(
                    _this.circleGroup.children.pop()
                );*/
                // --- 新增的circle(每次add都是circleGroup.children的最后一项)
                var newAddCircle = _this.circleGroup.children.pop();
                // --- 获取新排序的index
                var ri = _this.getNewCircleIndex([
                    newAddCircle.attrs.x,
                    newAddCircle.attrs.y
                ]);
                //console.log("---ri---",ri);
                try {
                    _this.circleGroup.children.splice(ri+1,0,newAddCircle);
                } catch (error) {
                    _this.circleGroup.children.push(newAddCircle);
                }
                // --- 刷新points坐标集合
                _this.refreshPoints();
                // ---
                _this.parentLayer.draw();
            });
        },
        // --- 刷新points坐标集合
        refreshPoints(){
            if (this.circleGroup.children.length) {
                this.points = null;
                this.points = [];
                // ---
                _.each(
                    _.map(this.circleGroup.children, function(item) {
                        return {
                            x: item.attrs.x,
                            y: item.attrs.y
                        };
                    }),
                    function(item) {
                        this.points.push(item.x);
                        this.points.push(item.y);
                    },
                    this
                );
                //console.log("---this.points---",this.points);
            } 
        },
        // --- 绘制line
        setLinePoints() {
            if (this.circleGroup.children.length) {
                // ---
                this.refreshPoints();
                // ---
                this.line.setPoints(this.points);
                // ---
                this.parentLayer.draw();
            }
            return this;
        },
        // --- 创建cricle点
        addCircle(options) {
            var _this = this;
            var opt = $.extend({},
                this.circleOptions,
                options || {}
            );
            var circle = new Konva.Circle(opt)
            this.circleGroup.add(
                circle
            );
            // --- circle加拖拽事件
            //console.log("---circle---",circle);
            // --- 拖动点的时候重新绘制line
            circle.on("dragmove", function() {
                // ---
                _this.setLinePoints();
            });
            // --- 拖动点结束
            circle.on("dragend", function() {

            });
            circle.on("mouseup", function(evt) {
                // --- 拖拽操作不能新增circle（不触发state的mouseup回调方法）
                evt.cancelBubble = true;
            });
            /* this.parentLayer.add(
                this.lineGroup,
                this.circleGroup
            ); */
            this.parentLayer.draw();
            //console.log("---this.parentLayer---",this.parentLayer);
            //console.log(Object.getOwnPropertyDescriptor(this.circleGroup,"children"));
            return this;
        },
        // --- 点击line添加circle时，通过坐标点连线判断新增的点在circleGroup.children中的下标,调整circle的顺序
        // --- 参数circleXY:新增circle的attrs中的x,y坐标 Array  [x,y]
        getNewCircleIndex(circleXY) {
            //var nowCircle = [400, 243];
            //var nowCircle = [400,88];
            var points = $.extend([],this.points);
            var newPoints = [];
            while (points.length) {
                newPoints.push(
                    points.splice(0, 2)
                );
            }
            //console.log("---newPoints---",newPoints);
            // --- 两点间连线
            var n1, n2;
            var ri;
            for (var i = 0; i < newPoints.length; i++) {
                n1 = i;
                n2 = n1 + 1;
                if (n2 >= newPoints.length) n2 = 0;
                /* console.log(n1 + "------" + newPoints[n1][0]);
                console.log(n1 + "------" + newPoints[n1][1]);
                console.log(n2 + "------" + newPoints[n2][0]);
                console.log(n2 + "------" + newPoints[n2][1]); */
                // ------
                var minX1, maxX1, minY1, maxY2;
                minX1 = _.min([
                    newPoints[n1][0],
                    newPoints[n2][0]
                ]);
                maxX1 = _.max([
                    newPoints[n1][0],
                    newPoints[n2][0]
                ]);
                minY1 = _.min([
                    newPoints[n1][1],
                    newPoints[n2][1]
                ]);
                maxY1 = _.max([
                    newPoints[n1][1],
                    newPoints[n2][1]
                ]);
                /* console.log("---minX1---", minX1);
                console.log("---maxX1---", maxX1);
                console.log("---minY1---", minY1);
                console.log("---maxY1---", maxY1); */
                if (
                    circleXY[0] >= minX1 && circleXY[0] <= maxX1 &&
                    circleXY[1] >= minY1 && circleXY[1] <= maxY1
                ) {
                    ri = i;
                    // --- 不要break(有些点的坐标值相差很小...)
                    //break;
                }

                if (n2 < newPoints.length - 1) {
                    n1 = n2 + 1;
                }
            }
            return ri;
        }
    };
    /*  */
    $.when($.ready).done(function() {
        // --- 画布...
        window.BZC = new BZ_Canvas({
            id: "konva-container",
            imageSrc: "./images/test.jpg",
            // --- stage的mouseup
            stageMUCBF(mui, BZC) {
                /* ----------------------点 + 线 操作 begin------------------------------- */
                BZC_CPL.addCircle({
                    x: mui.evt.x,
                    y: mui.evt.y
                }).setLinePoints();
                /* ----------------------点 + 线 操作 begin------------------------------- */





                return false;
                //console.log("---stageMDCBF_info---",mdi);
                //console.log("---BZC---",BZC);
                var circle = new Konva.Circle({
                    x: mdi.evt.clientX,
                    y: mdi.evt.clientY,
                    radius: 8,
                    fill: 'pink',
                    stroke: '#fff',
                    strokeWidth: 2,
                    draggable: true
                });
                console.log("---circle---", circle);
                //circle.zIndex(1);
                circle.flag = "konva_circle";
                // circle.on("dragstart",function(ev){
                //     console.log("---dragstart_ev---",ev);
                //     ev.evt.cancelBubble = true;
                // });
                BZC.layers[0].add(
                    circle
                );
                // ---
                //console.log("---line---",line);
                var circle_lines = _.findWhere(
                    BZC.layers[0].children, {
                        flag: "konva_line"
                    }
                );
                if (!circle_lines) {
                    var line = new Konva.Line({
                        points: [],
                        stroke: 'yellow',
                        strokeWidth: 4,
                        lineJoin: 'round',
                        /*
                         * line segments with a length of 33px
                         * with a gap of 10px
                         */
                        //dash: [33, 10]
                    });
                    line.flag = "konva_line";
                    BZC.layers[0].add(line);
                } else {
                    console.log("---circle_lines---", circle_lines);
                    var results = [];
                    _.each(BZC.layers[0].children, function(item) {
                        if (item.flag === "konva_circle") {
                            results.push(item.attrs.x);
                            results.push(item.attrs.y);
                        }
                    })
                    //console.log("---results---",results);
                    circle_lines.setPoints(
                        results
                    );
                    // --- 自动闭合 ??? 两个点以上
                    if (results.length / 2 > 2) {
                        results.push(
                            results[0],
                            results[1]
                        )
                        circle_lines.setPoints(
                            results
                        );
                    }
                }
                //console.log("---BZC.layers[0].children---",BZC.layers[0].children);
                // console.log("---BZC.layers[0].children---",BZC.layers[0].children);
                // _.map(BZC.layers[0].children,function(item){
                //     console.log(item.flag);
                // })
            }
        });
        /* ----------------------点 + 线 操作 begin------------------------------- */
        window.BZC_CPL = new BZ_CirclePlusLine({
            parentLayer:BZC.layers[0]
        });
        /* ----------------------点 + 线 操作 end------------------------------- */
        //console.log("---BZ_Canvas---",BZC);
        /* ----------------------test start------------------------------- */
        $("#hide-circle-btn").on("click",function(){
            console.log("---BZC_CPL.circleGroup---",BZC_CPL.circleGroup);
            if(BZC_CPL.circleGroup){
                if(BZC_CPL.circleGroup.isVisible()){
                    BZC_CPL.circleGroup.hide();
                    BZC_CPL.parentLayer.draw();
                }else{
                    BZC_CPL.circleGroup.show();
                    BZC_CPL.parentLayer.draw();
                }
                //console.log("------",BZC_CPL.circleGroup.isVisible());
            }
        });
        $("#hide-line-btn").on("click",function(){
            console.log("---BZC_CPL.lineGroup---",BZC_CPL.lineGroup);
            if(BZC_CPL.lineGroup){
                if(BZC_CPL.lineGroup.isVisible()){
                    BZC_CPL.lineGroup.hide();
                    BZC_CPL.parentLayer.draw();
                }else{
                    BZC_CPL.lineGroup.show();
                    BZC_CPL.parentLayer.draw();
                }
                //console.log("------",BZC_CPL.circleGroup.isVisible());
            }
        });
        /* ----------------------test end------------------------------- */
    });
    /*  */
    /* test begin */
    /* var nowCircle = [400, 243];
    //var nowCircle = [400,88];
    var points = [
        398, 98,
        620, 86,
        821, 85,
        880, 417,
        869, 665,
        759, 781,
        547, 791,
        411, 776
    ];
    var newPoints = [];
    while (points.length) {
        newPoints.push(
            points.splice(0, 2)
        );
    }
    //console.log("---newPoints---",newPoints);
    // --- 两点间连线
    var n1, n2;
    var ri;
    for (var i = 0; i < newPoints.length; i++) {
        n1 = i;
        n2 = n1 + 1;
        if (n2 >= newPoints.length) n2 = 0;
        console.log(n1 + "------" + newPoints[n1][0]);
        console.log(n1 + "------" + newPoints[n1][1]);
        // ------
        console.log(n2 + "------" + newPoints[n2][0]);
        console.log(n2 + "------" + newPoints[n2][1]);
        // ------
        var minX1, maxX1, minY1, maxY2;
        minX1 = _.min([
            newPoints[n1][0],
            newPoints[n2][0]
        ]);
        maxX1 = _.max([
            newPoints[n1][0],
            newPoints[n2][0]
        ]);
        minY1 = _.min([
            newPoints[n1][1],
            newPoints[n2][1]
        ]);
        maxY1 = _.max([
            newPoints[n1][1],
            newPoints[n2][1]
        ]);
        console.log("---minX1---", minX1);
        console.log("---maxX1---", maxX1);
        console.log("---minY1---", minY1);
        console.log("---maxY1---", maxY1);
        if (
            nowCircle[0] >= minX1 && nowCircle[0] <= maxX1 &&
            nowCircle[1] >= minY1 && nowCircle[1] <= maxY1
        ) {
            ri = i;
            alert(i);
            break;
        }

        if (n2 < newPoints.length - 1) {
            n1 = n2 + 1;
        }
    } */
    // ---
    /* test end */
})();